package exmple;

import org.junit.Test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.Properties;

public class Reflect {
    @Test
    public void app() throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException {
        Properties properties = new Properties();
        String path = Reflect.class.getResource("/config.properties").getPath();
        path = new URLDecoder().decode(path, "utf-8");
        properties.load(new FileInputStream(path));
        String name = properties.getProperty("class");
        impl s = (impl) Class.forName(name).newInstance();
        Student student = (Student) s;
        System.out.println(s);
    }

    public static void method() {
        try {
            Class<?> aClass = Class.forName("exmple.Student");
            Student student = constructor();
            Method update = aClass.getMethod("update", int.class);
            update.invoke(student, 100);
            System.out.println(student);
        } catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

    }

    @Test
    public void test() {
        try {
            Class<?> aClass = Class.forName("exmple.Student");
            Student student = constructor();
            Method update = aClass.getMethod("anInt", int.class);
            int x = (int) update.invoke(student, 100);
            System.out.println(x);
        } catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void getDeclared() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Student student = constructor();
        String[] quanxian = {"0", "public", "private"};
        Field[] fields = student.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field.getModifiers() == 1)
                System.out.println(field.get(student));
            else if (field.getModifiers() == 2) {
                String name = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
                Method method = student.getClass().getMethod(name);
                Object invoke = method.invoke(student);
                System.out.println(field.getName() + ":" + invoke);
            }
        }

    }

    @Test
    public void getFiled() {
        Student student = constructor();
        try {
            Field field = student.getClass().getField("age");//获取age的一个接口
            int x = (int) field.get(student);
            System.out.println(x);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public static Student constructor() {
        try {
            Class aclass = Class.forName("exmple.Student");
            Constructor constructor = aclass.getConstructor(new Class[]{
                    Integer.class, String.class, Float.class
            });
            Student student = (Student) constructor.newInstance(new Object[]{1, "wang", 1000f});
            System.out.println(student);
            return student;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return new Student();
    }

    public static void classfor() {
        //反射加载类
        try {
            Class aClass = Class.forName("exmple.Student");
            Student student = (Student) aClass.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();//类不存在,字符串错误
        } catch (IllegalAccessException e) {
            e.printStackTrace();//非法访问 private不能访问
        } catch (InstantiationException e) {
            e.printStackTrace();//实例化异常，抽象类
        }
    }

    public static void main(String[] args) {
        //classfor();
        //constructor();
        //method();

    }
}
